<script setup>
import { computed, defineComponent, useSlots } from "vue"

const props = defineProps({
  label: String,
  prop: String,
  defaultSlot: Object,
  header: Object,
  isShow: [Object, Boolean],
  enum: [Array, Function],
  enumMap: Map,
  fieldNames: {
    type: Object,
    default: () => ({
      label: 'label',
      value: 'value'
    })
  }
})

const slots = useSlots()

const columnEnum = computed(() => {
  const data = props.enumMap.get(props.prop)
  return data || []
})

const renderCellData = (val) => {
  return columnEnum.value.length ? columnEnum.value.find(item => item[props.fieldNames.value] === val)?.[props.fieldNames.label] : val
}

// 当使用插槽的方式渲染数据时，不知为何props会触发改变，props会触发改变就会使当前元素重新渲染。
// 那样情况下使用插槽的方式渲染的那一列就会排列到后面去，由此使用此方式解决 (后续测试发现并没有解决)
const ds = Object.assign({}, props.defaultSlot)
const dSlot = defineComponent(ds)
const headerSlot = defineComponent(props.header)
</script>

<template>
  <el-table-column
    v-bind="$attrs"
    :label="label"
    :prop="prop"
    v-if="isShow">
    <template #default="{ row, column, $index }">
      <!-- 通过列配置传入的 -->
      <dSlot v-if="defaultSlot" v-bind="{ row, column, index: $index }"></dSlot>
      <!-- 通过作用域插槽传入的 -->
      <template v-else-if="slots[prop]">
        <slot :name="prop" v-bind="{ row, column, index: $index }"></slot>
      </template>
      <span v-else>
        {{ renderCellData(row[prop]) }}
      </span>
      <slot></slot>
    </template>
    <template #header v-if="header">
      <headerSlot />
    </template>
  </el-table-column>
</template>